/**
  ******************************************************************************
  * @file    sym32l010_hal_adc.h
  * @author  AE Team
  * @version 1.0.3
  * @date    2024-05-28
  * @brief   Header file of ADC HAL module.
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2024 SIYIMicro.
  * All rights reserved.</center></h2>
  *
  *
  ******************************************************************************
  */


/******************************************************************************/
/* ADC 最高转换速率                                                           */
/******************************************************************************/

// -------------------------------------------------------------------------- // 
//       AVCC      |     SPS     |    ADC CLK                         // 
// ---------------------------------------------                      // 
//     1.7 - 2.1   |     500K    |     12MHz                          // 
// ---------------------------------------------                      // 
//     2.2 - 2.9   |      1M     |     24MHz                          // 
// ---------------------------------------------                      // 
//     3.0 - 5.5   |      2M     |     48MHz                          // 


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SYM32L010_HAL_ADC_H
#define __SYM32L010_HAL_ADC_H

#ifdef __cplusplus
extern "C" {
#endif


/******************************************************************************/
/* Include files                                                              */
/******************************************************************************/
#include "sym32l010_hal_def.h"


/******************************************************************************/
/* Global type definitions                                                    */
/******************************************************************************/
/* ADC工作时钟来源，ADC最高转换速率应符合用户手册要求 ---------------------------*/
typedef enum
{
    ADC_CLKSRC_DIV1            = (0x0UL << ADC_CR_CLKSRC_Pos),        // ADC工作时钟源为PCLK/1
    ADC_CLKSRC_DIV2            = (0x1UL << ADC_CR_CLKSRC_Pos),        // ADC工作时钟源为PCLK/2
    ADC_CLKSRC_DIV4            = (0x2UL << ADC_CR_CLKSRC_Pos),        // ADC工作时钟源为PCLK/4
    ADC_CLKSRC_DIV8            = (0x3UL << ADC_CR_CLKSRC_Pos),        // ADC工作时钟源为PCLK/8
} ADC_ClockSourceTypeDef;

/* ADC工作模式 ----------------------------------------------------------------*/
typedef enum
{
    ADC_WORKMODE_ONESHOT       = (0x0UL << ADC_CR_CONT_Pos),          // 单次转换模式
    ADC_WORKMODE_CONTINUE      = (0x1UL << ADC_CR_CONT_Pos)           // 持续转换模式
} ADC_WorkModeTypeDef;

/* ADC内置温度传感器 ----------------------------------------------------------*/
typedef enum
{
    ADC_TS_ENABLE              = (0x1UL << ADC_CR_TSEN_Pos),          // 使能内置温度传感器
    ADC_TS_DISABLE             = (0x0UL << ADC_CR_TSEN_Pos)           // 禁止内置温度传感器
} ADC_TempSensorEnTypeDef;

/* ADC内置基准电压源 ----------------------------------------------------------*/
typedef enum
{
    ADC_BGR_ENABLE             = (0x1UL << ADC_CR_BGREN_Pos),         // 使能内置基准电压源
    ADC_BGR_DISABLE            = (0x0UL << ADC_CR_BGREN_Pos)          // 禁止内置基准电压源
} ADC_BgrEnTypeDef;

/* ADC序列通道采样时钟数量 -----------------------------------------------------*/
typedef enum
{
    ADC_SAMPLE_CLK6            = (0x0UL),                             // 采样阶段持续6个ADC时钟
    ADC_SAMPLE_CLK7            = (0x1UL),                             // 采样阶段持续7个ADC时钟
    ADC_SAMPLE_CLK9            = (0x2UL),                             // 采样阶段持续9个ADC时钟
    ADC_SAMPLE_CLK12           = (0x3UL),                             // 采样阶段持续12个ADC时钟
    ADC_SAMPLE_CLK18           = (0x4UL),                             // 采样阶段持续18个ADC时钟
    ADC_SAMPLE_CLK24           = (0x5UL),                             // 采样阶段持续24个ADC时钟
    ADC_SAMPLE_CLK30           = (0x6UL),                             // 采样阶段持续30个ADC时钟
    ADC_SAMPLE_CLK42           = (0x7UL),                             // 采样阶段持续42个ADC时钟
    ADC_SAMPLE_CLK54           = (0x8UL),                             // 采样阶段持续54个ADC时钟
    ADC_SAMPLE_CLK70           = (0x9UL),                             // 采样阶段持续70个ADC时钟
    ADC_SAMPLE_CLK102          = (0xAUL),                             // 采样阶段持续102个ADC时钟
    ADC_SAMPLE_CLK134          = (0xBUL),                             // 采样阶段持续134个ADC时钟
    ADC_SAMPLE_CLK166          = (0xCUL),                             // 采样阶段持续166个ADC时钟
    ADC_SAMPLE_CLK198          = (0xDUL),                             // 采样阶段持续198个ADC时钟
    ADC_SAMPLE_CLK262          = (0xEUL),                             // 采样阶段持续262个ADC时钟
    ADC_SAMPLE_CLK390          = (0xFUL)                              // 采样阶段持续390个ADC时钟
} ADC_SqrChSampleTimeTypeDef;

/* ADC序列通道待转换输入源 -----------------------------------------------------*/
typedef enum
{
    ADC_IN0                    = (0x0UL),
    ADC_IN1                    = (0x1UL),
    ADC_IN2                    = (0x2UL),
    ADC_IN3                    = (0x3UL),
    ADC_IN4                    = (0x4UL),
    ADC_IN5                    = (0x5UL),
    ADC_IN6                    = (0x6UL),
    ADC_IN7                    = (0x7UL),
    ADC_IN8                    = (0x8UL),
    ADC_IN9                    = (0x9UL),
    ADC_IN10                   = (0xAUL),
    ADC_IN11                   = (0xBUL),
    ADC_IN12                   = (0xCUL),
    ADC_IN13                   = (0xDUL),
    ADC_IN_TS                  = (0xEUL),
    ADC_IN_BGR1V2              = (0xFUL)
} ADC_SqrChInputTypeDef;

/* ADC转换序列通道 ------------------------------------------------------------*/
typedef enum
{
    ADC_SQRCH_0                = (0x0UL),
    ADC_SQRCH_1                = (0x1UL),
    ADC_SQRCH_2                = (0x2UL),
    ADC_SQRCH_3                = (0x3UL),
    ADC_SQRCH_4                = (0x4UL),
    ADC_SQRCH_5                = (0x5UL),
    ADC_SQRCH_6                = (0x6UL),
    ADC_SQRCH_7                = (0x7UL)
} ADC_SqrChannelTypeDef;

/* ADC待转换序列通道数量 ------------------------------------------------------*/
typedef enum
{
    ADC_ENS_SQRCH0               = (0x0UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_1             = (0x1UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_2             = (0x2UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_3             = (0x3UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_4             = (0x4UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_5             = (0x5UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_6             = (0x6UL << ADC_CR_ENS_Pos),
    ADC_ENS_SQRCH0_7             = (0x7UL << ADC_CR_ENS_Pos)
} ADC_SqrEnsTypeDef;

/* ADC初始化结构体 ------------------------------------------------------------*/
typedef struct
{
    ADC_ClockSourceTypeDef       ClockSource;                         // ADC时钟源
    ADC_WorkModeTypeDef          WorkMode;                            // ADC工作模式配置
    ADC_TempSensorEnTypeDef      TempSensorEn;                        // ADC内置温度传感器使能配置
    ADC_BgrEnTypeDef             BgrEn;                               // ADC内置BGR基准电压使能配置
} ADC_InitTypeDef;

/* ADC 序列转换通道配置结构体 --------------------------------------------------*/
typedef struct
{
    ADC_SqrEnsTypeDef            SqrEns;                              // 待转换的序列通道数量
    ADC_SqrChInputTypeDef        SqrCh0In;                            // 序列通道 0 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh1In;                            // 序列通道 1 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh2In;                            // 序列通道 2 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh3In;                            // 序列通道 3 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh4In;                            // 序列通道 4 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh5In;                            // 序列通道 5 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh6In;                            // 序列通道 6 待转换输入源配置
    ADC_SqrChInputTypeDef        SqrCh7In;                            // 序列通道 7 待转换输入源配置
    ADC_SqrChSampleTimeTypeDef   SqrCh0Sam;                           // 序列通道 0 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh1Sam;                           // 序列通道 1 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh2Sam;                           // 序列通道 2 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh3Sam;                           // 序列通道 3 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh4Sam;                           // 序列通道 4 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh5Sam;                           // 序列通道 5 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh6Sam;                           // 序列通道 6 采样时间配置
    ADC_SqrChSampleTimeTypeDef   SqrCh7Sam;                           // 序列通道 7 采样时间配置
} ADC_SqrInitTypeDef;


/******************************************************************************/
/* Global pre-processor symbols/macros ('#define')                            */
/******************************************************************************/
/* 配置ADC相应输入管脚为模拟功能 -----------------------------------------------*/
#define AFx_ADCIN0_PA00()               (SYM_GPIOA->ANALOG_f.PIN0 = 1U)
#define AFx_ADCIN1_PA01()               (SYM_GPIOA->ANALOG_f.PIN1 = 1U)
#define AFx_ADCIN2_PA02()               (SYM_GPIOA->ANALOG_f.PIN2 = 1U)
#define AFx_ADCIN3_PA03()               (SYM_GPIOA->ANALOG_f.PIN3 = 1U)
#define AFx_ADCIN4_PA04()               (SYM_GPIOA->ANALOG_f.PIN4 = 1U)
#define AFx_ADCIN5_PA05()               (SYM_GPIOA->ANALOG_f.PIN5 = 1U)
#define AFx_ADCIN6_PA06()               (SYM_GPIOA->ANALOG_f.PIN6 = 1U)
#define AFx_ADCIN7_PB00()               (SYM_GPIOB->ANALOG_f.PIN0 = 1U)
#define AFx_ADCIN8_PB01()               (SYM_GPIOB->ANALOG_f.PIN1 = 1U)
#define AFx_ADCIN9_PB02()               (SYM_GPIOB->ANALOG_f.PIN2 = 1U)
#define AFx_ADCIN10_PB03()              (SYM_GPIOB->ANALOG_f.PIN3 = 1U)
#define AFx_ADCIN11_PB04()              (SYM_GPIOB->ANALOG_f.PIN4 = 1U)
#define AFx_ADCIN12_PB05()              (SYM_GPIOB->ANALOG_f.PIN5 = 1U)
#define AFx_ADCIN13_PB06()              (SYM_GPIOB->ANALOG_f.PIN6 = 1U)

/* ADC 转换触发源 -------------------------------------------------------------*/
#define ADC_TRS_None                    (0UL)
#define ADC_TRS_ATIM_TRGO               (ADC_TRIGGER_ATIMTRGO_Msk)
#define ADC_TRS_ATIM_TRGO2              (ADC_TRIGGER_ATIMTRGO2_Msk)
#define ADC_TRS_ATIM_CC1                (ADC_TRIGGER_ATIMCC1_Msk)
#define ADC_TRS_ATIM_CC2                (ADC_TRIGGER_ATIMCC2_Msk)
#define ADC_TRS_ATIM_CC3                (ADC_TRIGGER_ATIMCC3_Msk)
#define ADC_TRS_ATIM_CC4                (ADC_TRIGGER_ATIMCC4_Msk)
#define ADC_TRS_ATIM_CC5                (ADC_TRIGGER_ATIMCC5_Msk)
#define ADC_TRS_ATIM_CC6                (ADC_TRIGGER_ATIMCC6_Msk)
#define ADC_TRS_GTIM1_TRGO              (ADC_TRIGGER_GTIM1TRGO_Msk)
#define ADC_TRS_GTIM1_CC1               (ADC_TRIGGER_GTIM1CC1_Msk)
#define ADC_TRS_GTIM1_CC2               (ADC_TRIGGER_GTIM1CC2_Msk)
#define ADC_TRS_GTIM1_CC3               (ADC_TRIGGER_GTIM1CC3_Msk)
#define ADC_TRS_GTIM1_CC4               (ADC_TRIGGER_GTIM1CC4_Msk)
#define ADC_TRS_BTIM1_TRGO              (ADC_TRIGGER_BTIM1TRGO_Msk)
#define ADC_TRS_BTIM2_TRGO              (ADC_TRIGGER_BTIM2TRGO_Msk)
#define ADC_TRS_BTIM3_TRGO              (ADC_TRIGGER_BTIM3TRGO_Msk)
#define ADC_TRS_SPI1                    (ADC_TRIGGER_SPI1_Msk)
#define ADC_TRS_UART1                   (ADC_TRIGGER_UART1_Msk)
#define ADC_TRS_UART2                   (ADC_TRIGGER_UART2_Msk)

/* ADC AWD 待监测的输入通道 ---------------------------------------------------*/
#define ADC_AWD_IN0                     (ADC_AWDCR_IN0_Msk)
#define ADC_AWD_IN1                     (ADC_AWDCR_IN1_Msk)
#define ADC_AWD_IN2                     (ADC_AWDCR_IN2_Msk)
#define ADC_AWD_IN3                     (ADC_AWDCR_IN3_Msk)
#define ADC_AWD_IN4                     (ADC_AWDCR_IN4_Msk)
#define ADC_AWD_IN5                     (ADC_AWDCR_IN5_Msk)
#define ADC_AWD_IN6                     (ADC_AWDCR_IN6_Msk)
#define ADC_AWD_IN7                     (ADC_AWDCR_IN7_Msk)
#define ADC_AWD_IN8                     (ADC_AWDCR_IN8_Msk)
#define ADC_AWD_IN9                     (ADC_AWDCR_IN9_Msk)
#define ADC_AWD_IN10                    (ADC_AWDCR_IN10_Msk)
#define ADC_AWD_IN11                    (ADC_AWDCR_IN11_Msk)
#define ADC_AWD_IN12                    (ADC_AWDCR_IN12_Msk)
#define ADC_AWD_IN13                    (ADC_AWDCR_IN13_Msk)
#define ADC_AWD_TS                      (ADC_AWDCR_IN14_Msk)
#define ADC_AWD_BGR1V2                  (ADC_AWDCR_IN15_Msk)
#define ADC_AWD_ALL                     (0xFFFFUL)

/* ADC相关的Trim值 ------------------------------------------------------------*/
#define ADC_Bgr1V2_Voltage              (*((volatile uint16_t *)0x001007D2UL))  // 内置1.2V的校准值，以mV为单位
#define ADC_Ts_TA                       (*((volatile uint8_t  *)0x001007CDUL))  // TS出厂校准时的环境温度，以0.5℃为单位
#define ADC_Ts_Voltage                  (*((volatile uint16_t *)0x001007CEUL))  // TS出厂校准时测得到的电压值，以mV为单位

/* IER -----------------------------------------------------------------------*/
#define ADC_IT_SOURCE_AWDH              (ADC_IER_AWDH_Msk)            // 模拟看门狗阈值上限中断使能
#define ADC_IT_SOURCE_AWDL              (ADC_IER_AWDL_Msk)            // 模拟看门狗阈值下限中断使能
#define ADC_IT_SOURCE_EOS               (ADC_IER_EOS_Msk)             // 序列转换完成中断使能
#define ADC_IT_SOURCE_EOC               (ADC_IER_EOC_Msk)             // 转换完成中断使能

/* ISR -----------------------------------------------------------------------*/
#define ADC_IT_FLAG_AWDH                (ADC_ISR_AWDH_Msk)            // 模拟看门狗高阈值区间标志
#define ADC_IT_FLAG_AWDL                (ADC_ISR_AWDL_Msk)            // 模拟看门狗低阈值区间标志
#define ADC_IT_FLAG_EOS                 (ADC_ISR_EOS_Msk)             // 序列转换完成标志
#define ADC_IT_FLAG_EOC                 (ADC_ISR_EOC_Msk)             // 转换完成标志


/******************************************************************************/
/* Global macro function                                                      */
/******************************************************************************/
/**
  * @brief  获取 ADC中断触发源
  * @param  ITSOURCE: ADC中断触发源
  *                   @arg ADC_IT_SOURCE_AWDH
  *                   @arg ADC_IT_SOURCE_AWDL
  *                   @arg ADC_IT_SOURCE_EOS
  *                   @arg ADC_IT_SOURCE_EOC
  * @retval
  */
#define HAL_ADC_GET_IT_SOURCE(ITSOURCE) (SYM_ADC->IER & (ITSOURCE))

/**
  * @brief  使能 ADC中断触发源
  * @param  ITSOURCE: ADC中断触发源
  *                   @arg ADC_IT_SOURCE_AWDH
  *                   @arg ADC_IT_SOURCE_AWDL
  *                   @arg ADC_IT_SOURCE_EOS
  *                   @arg ADC_IT_SOURCE_EOC
  * @retval
  */
#define HAL_ADC_ENABLE_IT(ITSOURCE)     (SYM_ADC->IER |= (ITSOURCE))

/**
  * @brief  关闭 ADC中断触发源
  * @param  ITSOURCE: ADC中断触发源
  *                   @arg ADC_IT_SOURCE_AWDH
  *                   @arg ADC_IT_SOURCE_AWDL
  *                   @arg ADC_IT_SOURCE_EOS
  *                   @arg ADC_IT_SOURCE_EOC
  * @retval
  */
#define HAL_ADC_DISABLE_IT(ITSOURCE)    (SYM_ADC->IER &= ~((uint32_t)(ITSOURCE)))

/**
  * @brief  查询 ADC中断触发标志
  * @param  FLAG: ADC中断触发标志
  *               @arg ADC_IT_FLAG_AWDH
  *               @arg ADC_IT_FLAG_AWDL
  *               @arg ADC_IT_FLAG_EOS
  *               @arg ADC_IT_FLAG_EOC
  * @retval
  */
#define HAL_ADC_GET_FLAG(FLAG)          (SYM_ADC->ISR & (FLAG))

/**
  * @brief  清除 ADC中断触发标志
  * @param  FLAG: ADC中断触发标志
  *               @arg ADC_IT_FLAG_AWDH
  *               @arg ADC_IT_FLAG_AWDL
  *               @arg ADC_IT_FLAG_EOS
  *               @arg ADC_IT_FLAG_EOC
  * @retval
  */
#define HAL_ADC_CLR_FLAG(FLAG)          (SYM_ADC->ICR = ~((uint32_t)(FLAG)))


/******************************************************************************/
/* Exported variables ('extern', definition in C source)                      */
/******************************************************************************/


/******************************************************************************/
/* Global function prototypes ('extern', definition in C source)              */
/******************************************************************************/
void     HAL_ADC_Init(ADC_InitTypeDef *InitStruct);
void     HAL_ADC_DeInit(void);

void     HAL_ADC_BGR_Config(ADC_BgrEnTypeDef BgrEn);
void     HAL_ADC_TempSensor_Config(ADC_TempSensorEnTypeDef TempSensorEn);
void     HAL_ADC_ClockSource_Config(ADC_ClockSourceTypeDef ClockSource);
void     HAL_ADC_WorkMode_Config(ADC_WorkModeTypeDef WorkMode);

void     HAL_ADC_Enable(void);
void     HAL_ADC_Disable(void);

void     HAL_ADC_AWD_Config(uint32_t AwdInSel, uint16_t ThresholdHigh,
                                                      uint16_t ThresholdLow);

void     HAL_ADC_OneSqrChannel_Config(ADC_SqrChannelTypeDef SqrChannel,
                                             ADC_SqrChInputTypeDef Input,
                                             ADC_SqrChSampleTimeTypeDef SampleTime);

void     HAL_ADC_AllSqrChannel_Config(ADC_SqrInitTypeDef *SqrInitStruct);

void     HAL_ADC_Trigger_Config(uint32_t TriggerSource);
void     HAL_ADC_Start(void);
void     HAL_ADC_Stop(void);

uint16_t HAL_ADC_Result0_Read(void);
uint16_t HAL_ADC_Result1_Read(void);
uint16_t HAL_ADC_Result2_Read(void);
uint16_t HAL_ADC_Result3_Read(void);
uint16_t HAL_ADC_Result4_Read(void);
uint16_t HAL_ADC_Result5_Read(void);
uint16_t HAL_ADC_Result6_Read(void);
uint16_t HAL_ADC_Result7_Read(void);

void     HAL_ADC_WaitComplete(void);

float    HAL_ADC_BgrResult2Avcc(uint16_t Result);
float    HAL_ADC_TsResult2Tempreture(uint16_t Result, float Avcc);


#ifdef __cplusplus
}
#endif

#endif /* __SYM32L010_HAL_ADC_H */


/************************ (C) COPYRIGHT SIYIMicro *****END OF FILE*************/
